package com.my.screenadapter.mywebview;

import android.annotation.TargetApi;
import android.os.Build;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.webkit.JavascriptInterface;
import android.webkit.ValueCallback;
import android.webkit.WebSettings;
import android.webkit.WebView;

import com.my.screenadapter.R;

/**
 * webview 和 js 交互
 * http://www.jianshu.com/p/0b986d6e2e17
 * zyj 2017-10-19 09:53:10
 */
public class H5WebViewActivity extends AppCompatActivity {

    private WebView mWebView;

    private static final String TAG = "H5WebViewActivity===";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_h5_web_view);
        //加载assets文件夹下的test.html页面，文件截图如图1*
        mWebView = (WebView) findViewById(R.id.wv);
        mWebView.loadUrl("file:///android_asset/my.html");
        init();
        findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                androidCallH5();
            }
        });
    }


    private void init() {
        WebSettings webSettings = mWebView.getSettings();
        //设置为可调用js方法*
        webSettings.setJavaScriptEnabled(true);
        h5CallAndroid();
    }

    /**
     * H5如何调用android中的方法
     * 说白了就是新建一个类，里面写提供给H5操作的方法，并规定别名。
     */
    private void h5CallAndroid() {
        //这里我新建的class为JsInteration,方法为back(),规定的别名为android
        //h5用window.别名.类名里的方法名才能调用方法里面的内容，例如：window.android.back(); 本地给js映射
        mWebView.addJavascriptInterface(new JsInteration(),"android");
    }


    /**
     *   调用H5中的方法
     */
    @TargetApi(Build.VERSION_CODES.KITKAT)
    private void androidCallH5() {
        //①调用H5中无参无返回值的方法*
        mWebView.loadUrl("JavaScript:show()");
        //②调用H5中带返回值的方法*可以调用mWebView.evaluateJavascript()方法，
        // 该方法只在安卓4.4以上版本适用
        mWebView.evaluateJavascript("sum(1,2)", new ValueCallback<String>() {
            @Override
            public void onReceiveValue(String s) {
                Log.e(TAG,"onReceiveValue value=" + s);
            }
        });
        //③调用H5中带参数的方法*
        //当调用H5中带参数的方法时，势必要传入一个字符串，当传入固定字符串时，用单引号括起来即可；
        mWebView.loadUrl("javascript:alertMessage('哈哈')");
        // 当传入变量名时，需要用到转义符
        String content="9880------哈哈";
        mWebView.loadUrl("javascript:alertMessage(\""+content+"\")");
    }


    public class JsInteration{

//        http://blog.csdn.net/carson_ho/article/details/64904635
//        B1. Android 4.2版本之后
//        Google 在Android 4.2 版本中规定对被调用的函数以 @JavascriptInterface进行注解从而避免漏洞攻击
//
//        B2. Android 4.2版本之前
//        在Android 4.2版本之前采用拦截prompt（）进行漏洞修复。

        //在安卓4.2以上可以直接使用@JavascriptInterface注解来声明，下面是在一个本地Java方法
        //定义完这个方法后再调用mWebView.addJavascriptInterface()方法：
        // @JavascriptInterface//一定要写，不然H5调不到这个方法

        //js调用java的时候，如果设置了targetSdkVersion，当targetSdkVersion<17时没问题，targetSdkVersion>=17时不成功
        //如果您在编写HTML5应用，需要在JS代码中访问Java中的函数，则您会用到WebView的addJavascriptInterface()函数。因为安全问题，在Android4.2中(如果应用的android:targetSdkVersion数值为17+)JS只能访问带有 @JavascriptInterface注解的Java函数。
        //之前，任何Public的函数都可以在JS代码中访问，而Java对象继承关系会导致很多Public的函数都可以在JS中访问，其中一个重要的函数就是  getClass()。然后JS可以通过反射来访问其他一些内容。通过引入 @JavascriptInterface注解，则在JS中只能访问 @JavascriptInterface注解的函数。这样就可以增强安全性。
        //如果您的应用android:targetSdkVersion数值为17或者大于17记得添加 @JavascriptInterface 注解。
        @JavascriptInterface
        public String back(){
            return "我是java里的返回值 android back";
        }
    }






}
